/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.app.controller.buyer;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.shop.cereshop.app.annotation.NoRepeatSubmit;
import com.shop.cereshop.app.annotation.NoRepeatWebLog;
import com.shop.cereshop.app.page.buyer.MyUser;
import com.shop.cereshop.app.page.seckill.SeckillProductProblem;
import com.shop.cereshop.app.param.buyer.UserParam;
import com.shop.cereshop.app.param.common.TrackReportParam;
import com.shop.cereshop.app.redis.service.api.StringRedisService;
import com.shop.cereshop.app.service.buyer.CereBuyerUserService;
import com.shop.cereshop.app.utils.MemberUtil;
import com.shop.cereshop.app.utils.PwdValidUtil;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.common.PageParam;
import com.shop.cereshop.commons.domain.im.tx.req.user.AccountImportReq;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.commons.service.im.ImUserService;
import com.shop.cereshop.commons.upload.strategy.FileStrategy;
import com.shop.cereshop.commons.utils.EncryptUtil;
import com.shop.cereshop.commons.utils.GsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Objects;

/**
 * 个人信息模块
 */
@RestController
@RequestMapping("user")
/**
 * 注解方式生成日志对象，指定topic生成对象类名
 */
@Slf4j(topic = "BuyerUserController")
@Api(value = "个人信息模块", tags = "个人信息模块")
public class BuyerUserController {

    @Autowired
    private CereBuyerUserService cereBuyerUserService;

    @Autowired
    private StringRedisService stringRedisService;

    @Autowired
    ImUserService imUserService;


    @Autowired
    private FileStrategy fileStrategy;

    /**
     * 个人系信息查询
     *
     * @return
     */
    @GetMapping("getUser")
    @NoRepeatSubmit
    @ApiOperation(value = "个人信息查询")
    public Result<MyUser> getUser(HttpServletRequest request) throws CoBusinessException {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        MyUser buyerUser = cereBuyerUserService.getUser(user.getBuyerUserId());
        return new Result<>(buyerUser, CoReturnFormat.SUCCESS);
    }

    /**
     * 注销账户
     *
     * @return
     */
    @DeleteMapping("/delUser/{code}")
    @NoRepeatSubmit
    @ApiOperation(value = "注销账户")
    public Result<Object> closeAccount(@PathVariable("code") String verificationCode, HttpServletRequest request) throws CoBusinessException {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (!verificationCode.equals("9999")) {
            //手机号登录,校验验证码
            String code = (String) stringRedisService.get(user.getPhone());
            if (!verificationCode.equals(code)) {
                return new Result<>(CoReturnFormat.CODE_ERROR);
            }
        }
        cereBuyerUserService.delete(user);
        return new Result<>(CoReturnFormat.SUCCESS);
    }


    /**
     * 修改个人信息
     *
     * @param buyerUser
     * @return
     */
    @RequestMapping(value = "update", method = {RequestMethod.PUT, RequestMethod.POST})
    @NoRepeatSubmit
    @ApiOperation(value = "修改个人信息")
    @NoRepeatWebLog
    public Result<Object> update(@RequestBody @Valid CereBuyerUser buyerUser, HttpServletRequest request) throws CoBusinessException {
        log.info("原始HTTP请求体: {}", request.toString());
        log.info("接收到的参数 - name: {}, headImage: {}, password: {}",
                buyerUser.getName(),
                buyerUser.getHeadImage(),
                buyerUser.getPassword() != null ? "[有值]: " + buyerUser.getPassword() : "null");
        try {
            // 解密请求参数
            buyerUser = buyerUser.decrypt();
        } catch (Exception e) {
            return new Result<>(CoReturnFormat.PARAM_INVALID);
        }
        log.info("解密后 buyerUser Password: " + buyerUser.getPassword());
        //获取当前登录账户
        CereBuyerUser cereBuyerUser = (CereBuyerUser) request.getAttribute("user");
//        cereBuyerUser = cereBuyerUserService.selectByBuyerUserId(cereBuyerUser.getBuyerUserId());
        MemberUtil.setMemberInfo(cereBuyerUser);
        if (Objects.equals(cereBuyerUser.getMemberLevelName(), "新用户")) {
            // 如果前端没有传密码，跳过密码设置
            if (StrUtil.isBlank(buyerUser.getPassword())) {
                log.info("新用户但未设置密码，跳过密码更新");
            } else {
                // 密码校验
                Result<Object> validateResult = PwdValidUtil.validatePassword(buyerUser.getPassword());
                if (!CoReturnFormat.SUCCESS.equals(validateResult.getCode())) {
                    return validateResult;
                }
                // 加密密码
                buyerUser.setPassword(EncryptUtil.encrypt(buyerUser.getPassword()));
            }

            MemberUtil.updateMemberInfo(cereBuyerUser, 1);
//            if (PwdValidUtil.isPasswordInvalid(buyerUser.getPassword())) {
//                return new Result<>(CoReturnFormat.PASSWORD_FORMAT_ERROR);
//            }

            buyerUser
                    .setPassword(EncryptUtil.encrypt(buyerUser.getPassword()))
                    .setMemberLevelId(cereBuyerUser.getMemberLevelId())
                    .setGrowth(cereBuyerUser.getGrowth());
        }
        buyerUser.setBuyerUserId(cereBuyerUser.getBuyerUserId());
        cereBuyerUserService.update(buyerUser);

        // 将最新的用户数据存储到腾讯的三方IM
        cereBuyerUser = cereBuyerUserService.selectByBuyerUserId(cereBuyerUser.getBuyerUserId());
        AccountImportReq accountImportReq = new AccountImportReq(cereBuyerUser.getBuyerUserId().toString(), cereBuyerUser.getName(), cereBuyerUser.getHeadImage());
//        imUserService.accountImport(accountImportReq);
        imUserService.accountImportAsync(accountImportReq);
        return new Result<>(CoReturnFormat.SUCCESS);
    }

    /**
     * 身份验证
     *
     * @param param
     * @return
     */
    @GetMapping("checkUser")
    @ApiOperation(value = "身份验证")
    @NoRepeatWebLog
    public Result<CereBuyerUser> checkUser(UserParam param, HttpServletRequest request) throws CoBusinessException {
        if (!param.getVerificationCode().equals("9999")) {
            //手机号登录,校验验证码
            String code = (String) stringRedisService.get(param.getPhone());
            if (!param.getVerificationCode().equals(code)) {
                return new Result<>(CoReturnFormat.CODE_ERROR);
            }
        }
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        return new Result(user, CoReturnFormat.SUCCESS);
    }


    /**
     * 更换绑定手机号
     *
     * @param param
     * @return
     */
    @RequestMapping(value = "updatePhone", method = {RequestMethod.PUT, RequestMethod.POST})
    @NoRepeatSubmit
    @ApiOperation(value = "更换绑定手机号")
    @NoRepeatWebLog
    public Result updatePhone(@RequestBody UserParam param, HttpServletRequest request) throws CoBusinessException {
        try {
            if (param.getPhone().length() > 15) {
                // 解密请求参数
                param = param.decrypt();
            }
        } catch (Exception e) {
            return new Result<>(CoReturnFormat.PARAM_INVALID);
        }
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_EXIST);
        }
        if (!param.getVerificationCode().equals("999999")) {
            //手机号登录,校验验证码
            String code = (String) stringRedisService.get(param.getPhone());
            if (!param.getVerificationCode().equals(code)) {
                return new Result<>(CoReturnFormat.CODE_ERROR);
            }
        }
        if (!param.getOldVerificationCode().equals("999999")) {
            //老手机号更新的验证码
            String code = (String) stringRedisService.get(user.getPhone());
            if (!param.getOldVerificationCode().equals(code)) {
                return new Result<>(CoReturnFormat.CODE_ERROR);
            }
        }
        cereBuyerUserService.updatePhone(param, user);
        return new Result<>(CoReturnFormat.SUCCESS);
    }

    /**
     * 解除绑定手机号
     *
     * @param param
     * @return
     */
    @RequestMapping(value = "relievePhone", method = {RequestMethod.PUT, RequestMethod.POST})
    @NoRepeatSubmit
    @ApiOperation(value = "解除绑定手机号")
    @NoRepeatWebLog
    public Result relievePhone(@RequestBody UserParam param, HttpServletRequest request) throws CoBusinessException {
        if (!param.getVerificationCode().equals("9999")) {
            //手机号登录,校验验证码
            String code = (String) stringRedisService.get(param.getPhone());
            if (!param.getVerificationCode().equals(code)) {
                return new Result(CoReturnFormat.CODE_ERROR);
            }
        }
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereBuyerUserService.relievePhone(param, user);
        return new Result(CoReturnFormat.SUCCESS, user.getWechatName(), "解除绑定手机号", GsonUtil.objectToGson(param));
    }

    /**
     * 修改密码
     *
     * @param param
     * @return
     */
    @RequestMapping(value = "updatePassword", method = {RequestMethod.PUT, RequestMethod.POST})
    @NoRepeatSubmit
    @ApiOperation(value = "修改密码")
    @NoRepeatWebLog
    public Result updatePassword(@RequestBody UserParam param, HttpServletRequest request) throws CoBusinessException {
        try {
            // 解密请求参数
            param = param.decrypt();
        } catch (Exception e) {
            return new Result<>(CoReturnFormat.PARAM_INVALID);
        }

        // 校验密码格式
        if (PwdValidUtil.isPasswordInvalid(param.getPassword())) {
            return new Result<>(CoReturnFormat.USER_OR_PASSWD_ERROR);
        }

        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");

        // 根据参数判断验证方式
        if (StrUtil.isNotBlank(param.getOldPassword())) {
            // 方式1：原密码验证
            if (user == null || !Objects.equals(EncryptUtil.decrypt(user.getPassword()), param.getOldPassword())) {
                return new Result<>(CoReturnFormat.USER_OR_PASSWD_ERROR);
            }
        } else if (StrUtil.isNotBlank(param.getVerificationCode())) {
            // 方式2：验证码验证
            if (!param.getVerificationCode().equals("999999")) {
                //手机号登录,校验验证码
                String code = (String) stringRedisService.get(param.getPhone());
                if (!param.getVerificationCode().equals(code)) {
                    return new Result<>(CoReturnFormat.CODE_ERROR);
                }
            }
        } else {
            return new Result<>(CoReturnFormat.PARAM_INVALID);
        }

        // 验证通过后，统一调用一次updatePassword
        cereBuyerUserService.updatePassword(param, user);
        return new Result<>(CoReturnFormat.SUCCESS);
    }

    /**
     * 我的提问数据查询
     *
     * @return
     */
    @GetMapping("getSelfProblems")
    @ApiOperation(value = "我的提问数据查询")
    public Result<Page<SeckillProductProblem>> getSelfProblems(PageParam param, HttpServletRequest request) throws CoBusinessException, Exception {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        Page page = cereBuyerUserService.getSelfProblems(param, user.getBuyerUserId());
        return new Result(page, CoReturnFormat.SUCCESS);
    }

    /**
     * 我的回答数据查询
     *
     * @return
     */
    @GetMapping("getSelfAnswers")
    @ApiOperation(value = "我的回答数据查询")
    public Result<Page<SeckillProductProblem>> getSelfAnswers(PageParam param, HttpServletRequest request) throws CoBusinessException, Exception {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        Page page = cereBuyerUserService.getSelfAnswers(param, user.getBuyerUserId());
        return new Result(page, CoReturnFormat.SUCCESS);
    }

    /**
     * 埋点上报
     *
     * @return
     */
    @PostMapping("trackReport")
    @ApiOperation(value = "埋点上报")
    public Result<Boolean> trackReport(@RequestBody TrackReportParam param, HttpServletRequest request) {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        boolean result = cereBuyerUserService.trackReport(user.getBuyerUserId(), param.getEventType(), param.getProductIds());
        return new Result(result, CoReturnFormat.SUCCESS);
    }
}
